package org.ko.core.domain.support;

import java.util.HashMap;
import java.util.Map;


/**
 * 查询辅助类,为HQL提供两种传参方式 ,JPA提供了两种常用的参数绑定方式,1:基于参数名,2:基于参数下标,以下两种传参方式正是基于此而设计的
 * 功能描述:
 * 传参方式
 * 		1:hash列表,key:value方式.
* 		2:不定数组方式,默认提供hash方式.
 * 
 * 其它功能:
 * 		提供传递分页查询体(Pageable),排序体(Sort)功能.
 * 
 * 
 * 在实际查询中,只能出现一种传参方式,不能同时使用,一旦调用mapArray(Object ...args)方法,则变成数组传参模式,且不提供切换回hash模式的方法
 * 
 <pre>
  Usage:
  例如在UserDao中
	hash模式:
	update("update User u set u.userNo = :userNo,u.name=:name,u.email=:email,u.telephone=:telephone,u.isValid=:isValid where u.id = :id", 
			P.begin()
			.bind("id", id)
			.bind("userNo", userNo)
			.bind("name", name)
			.bind("email", email)
			.bind("telephone", telephone)
			.bind("isValid", isValid)
			);
	
	array模式:
	update("update User set role=?1 where id=?2", P.begin().mapArray(role,id));
	
	使用分页查询体
	findPage("select u from User u where u.name like :name or u.userNo like :userNo", P.begin().Pageable(p).bindlike("name", name).bindlike("userNo", userNo));
	
</pre>	
 * 
 * @author byTheWay
 * @date 2013-8-21
 */
public class P {
	/**
	 * 支持hash模式的参数列表
	 */
	private Map<String, Object> mapParams = new HashMap<String, Object>();
	/**
	 * 支持数组模式的参数列表
	 */
	private Object [] arrayParams = null;
	/**
	 * 支持排序的参数列表
	 */
//	private List<Sort> orders = new ArrayList<Sort>();
	/**
	 * 当前使用传参模式,默认hash模式
	 */
	private MapType mapType = MapType.map;
	/**
	 * 支持分页查询体参数
	 */
//	private Pageable pageable = new Pageable();
	
	private Integer first;
	private Integer count;
	
	private StringBuilder hql;
	/**
	 * 支持模式枚举
	 */
	public enum MapType {
		map,//hash模式
		array //数组模式
		;
		public static MapType fromString(String value) {
			return MapType.valueOf(value.toLowerCase());
		}
	}
	public P(String hql) {
		this.hql = new StringBuilder(hql);
	}
	public P() {
		// TODO Auto-generated constructor stub
	}
	
	public String getHql() {
		return hql.toString();
	}
	/**
	 * 使用不定数组传参模式
	 * @param args
	 * @return 自身对象,方便串联调用
	 */
	public P mapArray(Object ...args){
		mapType = MapType.array;
		this.arrayParams =  args;
		return this;
	}
	/**
	 * 使用hash模式绑定参数
	 * @param key,参数名
	 * @param value,参数值
	 * @return 自身对象,方便串联调用
	 */
	public P bind(String key,Object value){
		mapParams.put(key, value);
		return this;
	}
	/**
	 * 提供模糊查找参数绑定
	 * @param key
	 * @param value
	 * @return 自身对象,方便串联调用
	 */
	public P bindlike(String key,Object value) {
		return bind(key,"%"+value+"%");
	}
	/**
	 * 排序参数,可连续添加多个
	 * @param property,需要排序的属性名
	 * @param dir,排序方向,asc 正向,desc 逆向
	 * @return 自身对象,方便串联调用
	 */
//	public P orderBy(String property,Sort.Direction dir){
//		orders.add(new Sort(property, dir));
//		return this;
//	}
	/**
	 * 启用分页查询
	 * @param pageable
	 * @return
	 */
//	public P paging(Pageable pageable){
//		if(null==pageable)return this;
//		this.orders.addAll(pageable.getOrders());
//		this.pageable = pageable;
//		this.first = pageable.getStart();
//		this.count = pageable.getLimit();
//		return this;
//	}
	
	public P first(Integer first){
		this.first = first;
		return this;
	}
	public P count(Integer count){
		this.count = count;
		return this;
	}
	
	/**
	 * 静态方法,生成一个P 对象
	 * @return
	 */
	public static P begin(){
		return new P();
	}
	public static P begin(String hql){
		return new P(hql);
	}
	//getter  ...
	public Object[] getArrayParams() {
		return arrayParams;
	}
	public Integer getFirst() {
		return first;
	}
	public Integer getCount() {
		return count;
	}
	public Map<String, Object> getMapParams() {
		return mapParams;
	}
	
//	public Pageable getPageable() {
//		return pageable;
//	}
//	public List<Sort> getOrders() {
//		return orders;
//	}
	public MapType getMapType() {
		return mapType;
	}
	
	
}
